import Vue from 'vue'
import Main from './main.vue'
import { getStyle, addClass, removeClass, afterLeave } from './util'

const Mask = Vue.extend(Main)

const loadingDirective = {}
loadingDirective.install = Vue => {
  const toggleLoading = (el, binding) => {
    if (binding.value) {
      Vue.nextTick(() => {
        el.originalPosition = getStyle(el, 'position')
        insertDom(el, el, binding)
      })
    } else {
      afterLeave(el.instance, _ => { // 做个transition
        el.domVisible = false
        removeClass(el, 'yd-loading-parent--relative')
      }, 300, true)
      el.instance.existDom = false
    }
  }
  const insertDom = (parent, el, binding) => {
    if (!el.domVisible && getStyle(el, 'display') !== 'none') {
      // 给mask更新样式
      Object.keys(el.maskStyle).forEach(property => {
        el.mask.style[property] = el.maskStyle[property]
      })
      // 给父级添加relative
      if (el.originalPosition !== 'absolute' && el.originalPosition !== 'fixed') {
        addClass(parent, 'yd-loading-parent--relative')
      }

      el.domVisible = true

      parent.appendChild(el.mask)
      Vue.nextTick(() => {
        el.instance.existDom = true
      })

      // 标明存在这个指令,为了指令销毁的时候判断
      el.domInserted = true
    }
  }

  Vue.directive('yd-loading', {
    bind: function (el, binding, vnode) {
      const textExr = el.getAttribute('yd-loading-text')
      const typeExr = el.getAttribute('yd-loading-type') || 1
      const backgroundExr = el.getAttribute('yd-loading-background')
      const customClassExr = el.getAttribute('yd-loading-custom-class')
      const zIndex = el.getAttribute('yd-loading-zIndex')
      const vm = vnode.context
      const mask = new Mask({
        el: document.createElement('div'),
        data: {
          text: vm && vm[textExr] || textExr,
          type: vm && vm[typeExr] || typeExr,
          background: vm && vm[backgroundExr] || backgroundExr,
          customClass: vm && vm[customClassExr] || customClassExr,
          zIndex: vm && vm[zIndex] || zIndex
        }
      })

      el.instance = mask
      el.mask = mask.$el
      el.maskStyle = {
        position: 'absolute'
      }
      binding.value && toggleLoading(el, binding)
    },

    update: function (el, binding) {
      if (binding.oldValue !== binding.value) {
        toggleLoading(el, binding)
      }
    },

    unbind: function (el, binding) {
      if (el.domInserted) {
        el.mask &&
          el.mask.parentNode &&
          el.mask.parentNode.removeChild(el.mask)
        toggleLoading(el, { value: false, modifiers: binding.modifiers })
      }
      el.instance && el.instance.$destroy()
    }
  })
}

export default loadingDirective
